home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / jade / src / amiga_windows.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  17KB  |  662 lines

  1. /* amiga_windows.c -- Window handling for AmigaDOS
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22. #include "revision.h"
  23.  
  24. /* The SET_WRITE_MASK() things needs all this.    */
  25. #ifdef _DCC
  26. # define  GfxBase_DECLARED
  27. #endif
  28. #include <clib/graphics_protos.h>
  29. #include <graphics/gfxbase.h>
  30. #include <graphics/gfxmacros.h>
  31. extern struct GfxBase *GfxBase;
  32.  
  33. #define INTUI_V36_NAMES_ONLY
  34. #include <clib/intuition_protos.h>
  35. #include <intuition/gadgetclass.h>
  36. #include <clib/diskfont_protos.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39.  
  40. _PR int sys_sleep_vw(VW *);
  41. _PR int sys_unsleep_vw(VW *);
  42. _PR void sys_new_vw(VW *);
  43. _PR void sys_kill_vw(VW *);
  44. _PR void sys_update_dimensions(VW *);
  45. _PR void sys_update_scroller(VW *);
  46. _PR struct Window *sys_new_window(VW *, VW *, bool);
  47. _PR void sys_kill_window(VW *);
  48. static void close_shared_window(struct Window *);
  49. static void strip_intui_messages(struct MsgPort *, struct Window *);
  50. _PR struct IntuiMessage *ami_get_win_imsg(struct Window *);
  51. _PR void sys_activate_win(VW *);
  52. _PR void sys_set_vw_pos(VW *, long, long, long, long);
  53. _PR int ami_ezreq(u_char *, u_char *, long, ...);
  54. _PR int sys_set_font(VW *);
  55. _PR void sys_unset_font(VW *);
  56. _PR void sys_reset_sleep_titles(TX *);
  57. _PR bool sys_get_mouse_pos(POS *, VW *);
  58. _PR void sys_windows_init(void);
  59.  
  60. #define IDCMP (IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE \
  61.     | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_RAWKEY \
  62.     | IDCMP_ACTIVEWINDOW | IDCMP_GADGETUP | IDCMP_GADGETUP \
  63.     | IDCMP_INTUITICKS)
  64.  
  65. #define SIDCMP (IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY | IDCMP_INTUITICKS)
  66.  
  67. #define WFLAGS (WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET \
  68.     | WFLG_SIZEGADGET | WFLG_REPORTMOUSE | WFLG_ACTIVATE | WFLG_RMBTRAP \
  69.     | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH)
  70.  
  71. #define SWFLAGS (WFLG_DRAGBAR | WFLG_ACTIVATE \
  72.     | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH | WFLG_RMBTRAP)
  73.  
  74. static const u_char *window_title = VERSSTRING;
  75. static struct MsgPort *shared_window_port;
  76.  
  77. #ifdef AMIGA_NEED_VARARGS_STUBS
  78. ULONG
  79. SetGadgetAttrs(struct Gadget *gadget, struct Window *window, struct Requester *req, unsigned long tag1, ...)
  80. {
  81.     return(SetGadgetAttrsA(gadget, window, req, (struct TagItem *)&tag1));
  82. }
  83. APTR
  84. NewObject(struct IClass *class, UBYTE *classID, unsigned long tag1, ...)
  85. {
  86.     return(NewObjectA(class, classID, (struct TagItem *)&tag1));
  87. }
  88. #endif /* AMIGA_NEEDS_VARARGS_STUBS */
  89.  
  90. /*
  91.  * Have I screwed this up??
  92.  */
  93. int
  94. sys_sleep_vw(VW *vw)
  95. {
  96.     int rc = FALSE;
  97.     struct Window *swin;
  98.     if(swin = OpenWindowTags(NULL,
  99.                  WA_Left, vw->vw_Window->LeftEdge,
  100.                  WA_Top, vw->vw_Window->TopEdge,
  101.                  WA_Width, 150,
  102.                  WA_Height, vw->vw_Window->BorderTop,
  103.                  WA_IDCMP, 0,
  104.                  WA_Flags, SWFLAGS,
  105.                  WA_Title, VSTR(vw->vw_Tx->tx_BufferName),
  106.                  WA_AutoAdjust, TRUE,
  107.                  WA_PubScreenName, VSTR(vw->vw_WindowSys.ws_ScreenName),
  108.                  WA_PubScreenFallBack, TRUE,
  109.                  TAG_END))
  110.     {
  111.     swin->UserPort = shared_window_port;
  112.     ModifyIDCMP(swin, SIDCMP);
  113.  
  114.     vw->vw_WindowSys.ws_OldDimensions[0] = vw->vw_Window->LeftEdge;
  115.     vw->vw_WindowSys.ws_OldDimensions[1] = vw->vw_Window->TopEdge;
  116.     vw->vw_WindowSys.ws_OldDimensions[2] = vw->vw_Window->Width;
  117.     vw->vw_WindowSys.ws_OldDimensions[3] = vw->vw_Window->Height;
  118.  
  119.     ami_clear_menu(vw->vw_Window);
  120.     Forbid();
  121.     strip_intui_messages(vw->vw_Window->UserPort, vw->vw_Window);
  122.     vw->vw_Window->UserPort = NULL;
  123.     ModifyIDCMP(vw->vw_Window, 0L);
  124.     Permit();
  125.     CloseWindow(vw->vw_Window);
  126. #ifndef NOSCRLBAR
  127.     if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_SBar.gad)
  128.     {
  129.         DisposeObject(vw->vw_SBar.gad);
  130.         vw->vw_SBar.gad = NULL;
  131.     }
  132. #endif
  133.     vw->vw_Window = swin;
  134.     vw->vw_WindowSys.ws_Rp = swin->RPort;
  135.     vw->vw_Flags |= VWFF_SLEEPING;
  136.     swin->UserData = (BYTE *)vw;
  137.     rc = TRUE;
  138.     }
  139.     else
  140.     cmd_signal(sym_error, LIST_1(MKSTR("Can't open window")));
  141.     return(rc);
  142. }
  143.  
  144. int
  145. sys_unsleep_vw(VW *vw)
  146. {
  147.     int rc = TRUE;
  148.     if(vw->vw_Flags & VWFF_SLEEPING)
  149.     {
  150.     struct Window *oldwin = vw->vw_Window;
  151.     if(sys_new_window(vw, vw, FALSE))
  152.     {
  153.         Forbid();
  154.         strip_intui_messages(oldwin->UserPort, oldwin);
  155.         oldwin->UserPort = NULL;
  156.         ModifyIDCMP(oldwin, 0L);
  157.         Permit();
  158.         CloseWindow(oldwin);
  159.         vw->vw_Flags &= ~VWFF_MESSAGE;
  160.         sys_update_dimensions(vw);
  161. #ifndef NOSCRLBAR
  162.         sys_update_scroller(vw);
  163. #endif
  164.         vw->vw_Flags |= VWFF_FORCE_REFRESH;
  165.     }
  166.     else
  167.         rc = FALSE;
  168.     }
  169.     return(rc);
  170. }
  171.  
  172. void
  173. sys_new_vw(VW *vw)
  174. {
  175. }
  176.  
  177. void
  178. sys_kill_vw(VW *vw)
  179. {
  180. }
  181.  
  182. void
  183. sys_update_dimensions(VW *vw)
  184. {
  185.     if(vw->vw_Window && ((vw->vw_Flags & VWFF_SLEEPING) == 0))
  186.     {
  187.     struct Window *wd = vw->vw_Window;
  188.  
  189.     vw->vw_MessageLineY = wd->Height - wd->BorderBottom
  190.         - vw->vw_FontY - 2;
  191.     vw->vw_MessageFontY = vw->vw_MessageLineY + 2 + FONT_ASCENT(vw);
  192.  
  193.     vw->vw_XStartPix = (UWORD)wd->BorderLeft;
  194.     vw->vw_YStartPix = (UWORD)wd->BorderTop;
  195.     vw->vw_XEndPix = wd->Width - (UWORD)wd->BorderRight - 1;
  196.     vw->vw_YEndPix = (vw->vw_MessageLineY - 1);
  197.     vw->vw_XWidthPix = vw->vw_XEndPix - vw->vw_XStartPix;
  198.     vw->vw_YHeightPix = vw->vw_YEndPix - vw->vw_YStartPix;
  199.  
  200.     vw->vw_FontStart = vw->vw_YStartPix + vw->vw_Font->tf_Baseline;
  201.  
  202.     vw->vw_MaxX = (vw->vw_XWidthPix / vw->vw_FontX);
  203.     vw->vw_MaxY = (vw->vw_YHeightPix / vw->vw_FontY);
  204.     if((vw->vw_XStepRatio <= 0)
  205.        || ((vw->vw_XStep = vw->vw_MaxX / vw->vw_XStepRatio) <= 0))
  206.         vw->vw_XStep = 1;
  207.     if((vw->vw_YStepRatio <= 0)
  208.        || ((vw->vw_YStep = vw->vw_MaxY / vw->vw_YStepRatio) <= 0))
  209.         vw->vw_YStep = 1;
  210.     }
  211. }
  212.  
  213. #ifndef NOSCRLBAR
  214. void
  215. sys_update_scroller(VW *vw)
  216. {
  217.     if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_SBar.gad)
  218.     {
  219.     vw->vw_SBar.top = vw->vw_StartLine;
  220.     vw->vw_SBar.total = vw->vw_Tx->tx_NumLines;
  221.     SetGadgetAttrs(vw->vw_SBar.gad, vw->vw_Window, NULL,
  222.                PGA_Visible, vw->vw_MaxY,
  223.                PGA_Total, vw->vw_SBar.total,
  224.                PGA_Top, vw->vw_SBar.top,
  225.                TAG_END);
  226.     }
  227. }
  228. #endif
  229.  
  230. /*
  231.  * Opens an editor window. Sets up the shared IDCMP
  232.  */
  233. struct Window *
  234. sys_new_window(VW *oldVW, VW *vw, bool useDefDims)
  235. {
  236.     u_short *dimensions;
  237.     struct Screen *scr;
  238.     struct Window *res = NULL;
  239.     bool truedims = FALSE;
  240.     if(!useDefDims && oldVW)
  241.     {
  242.     if(oldVW->vw_Flags & VWFF_SLEEPING)
  243.         dimensions = oldVW->vw_WindowSys.ws_OldDimensions;
  244.     else
  245.         dimensions = &oldVW->vw_Window->LeftEdge;
  246.     truedims = TRUE;
  247.     }
  248.     else
  249.     dimensions = def_dims;
  250.     if(scr = LockPubScreen(*VSTR(vw->vw_WindowSys.ws_ScreenName)
  251.                ? VSTR(vw->vw_WindowSys.ws_ScreenName)
  252.                : NULL))
  253.     {
  254. #ifndef NOSCRLBAR
  255.     if(vw->vw_SBar.gad = NewObject(NULL, "propgclass",
  256.                        GA_RelRight, -13,
  257.                        GA_Top, 1 + scr->WBorTop + scr->Font->ta_YSize + 1,
  258.                        GA_Width, 10,
  259.                        GA_RelHeight, -12 - (scr->WBorTop + scr->Font->ta_YSize + 1),
  260.                        GA_RelVerify, TRUE,
  261.                        GA_Immediate, TRUE,
  262.                        GA_FollowMouse, TRUE,
  263.                        GA_RightBorder, TRUE,
  264.                        PGA_Borderless, TRUE,
  265.                        PGA_Freedom, FREEVERT,
  266.                        PGA_Total, 1,
  267.                        PGA_Visible, 1,
  268.                        PGA_Top, 0,
  269.                        PGA_NewLook, TRUE,
  270.                        TAG_END))
  271.     {
  272. #endif
  273.         if(res = OpenWindowTags(NULL,
  274.                     WA_Left, dimensions[0],
  275.                     WA_Top, dimensions[1],
  276.                     WA_InnerWidth, truedims ? dimensions[2] : (dimensions[2] * vw->vw_FontX + 1),
  277.                     WA_InnerHeight, truedims ? dimensions[3] : (dimensions[3] + 1) * vw->vw_FontY + 3,
  278.                     WA_IDCMP, shared_window_port ? 0 : IDCMP,
  279.                     WA_MinWidth, 80,
  280.                     WA_MinHeight, 40,
  281.                     WA_MaxWidth, ~0,
  282.                     WA_MaxHeight, ~0,
  283. #if AMIGA_INCLUDE_VER >= 39
  284.                     WA_Flags, WFLAGS | WFLG_NEWLOOKMENUS,
  285. #else
  286.                     WA_Flags, WFLAGS,
  287. #endif
  288. #ifndef NOSCRLBAR
  289.                     WA_Gadgets, vw->vw_SBar.gad,
  290. #endif
  291.                     WA_Title, window_title,
  292.                     WA_AutoAdjust, TRUE,
  293.                     WA_PubScreen, scr,
  294.                     WA_RptQueue, 2,
  295.                     TAG_END))
  296.         {
  297.         if(shared_window_port)
  298.         {
  299.             res->UserPort = shared_window_port;
  300.             ModifyIDCMP(res, IDCMP);
  301.         }
  302.         else
  303.             shared_window_port = res->UserPort;
  304.         vw->vw_Window = res;
  305.         ami_set_menu(res);
  306.         vw->vw_WindowSys.ws_Rp = res->RPort;
  307.         res->UserData = (BYTE *)vw;
  308.         SetFont(vw->vw_WindowSys.ws_Rp, vw->vw_Font);
  309.         SET_WRITE_MASK(vw->vw_WindowSys.ws_Rp, 1);
  310.         }
  311. #ifndef NOSCRLBAR
  312.         else
  313.         DisposeObject(vw->vw_SBar.gad);
  314.     }
  315. #endif
  316.     UnlockPubScreen(NULL, scr);
  317.     }
  318.     return(res);
  319. }
  320. void
  321. sys_kill_window(VW *vw)
  322. {
  323.     ami_clear_menu(vw->vw_Window);
  324.     close_shared_window(vw->vw_Window);
  325. #ifndef NOSCRLBAR
  326.     if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_SBar.gad)
  327.     {
  328.     DisposeObject(vw->vw_SBar.gad);
  329.     vw->vw_SBar.gad = NULL;
  330.     }
  331. #endif
  332. }
  333.  
  334. /*
  335.  * Code to close a window who's sharing a UserPort -- taken from
  336.  * CloseWindow() autodoc.
  337.  */
  338. static void
  339. close_shared_window(struct Window *win)
  340. {
  341.     ami_clear_menu(win);
  342.     if(window_count > 1)
  343.     {
  344.     Forbid();
  345.     strip_intui_messages(win->UserPort, win);
  346.     win->UserPort = NULL;
  347.     ModifyIDCMP(win, 0L);
  348.     Permit();
  349.     }
  350.     else
  351.     shared_window_port = NULL;
  352.     CloseWindow(win);
  353. }
  354.  
  355. static void
  356. strip_intui_messages(struct MsgPort *mp, struct Window *win)
  357. {
  358.     struct IntuiMessage *msg;
  359.     struct Node *succ;
  360.  
  361.     msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  362.     while(succ = msg->ExecMessage.mn_Node.ln_Succ)
  363.     {
  364.     if(msg->IDCMPWindow == win)
  365.     {
  366.         Remove((struct Node *)msg);
  367.         ReplyMsg((struct Message *)msg);
  368.     }
  369.     msg = (struct IntuiMessage *)succ;
  370.     }
  371. }
  372.  
  373. /*
  374.  * Gets the next Imsg for the specified window -- this is used for event
  375.  * loops local to a single window
  376.  */
  377. struct IntuiMessage *
  378. ami_get_win_imsg(struct Window *win)
  379. {
  380.     struct IntuiMessage *msg;
  381.     struct Node *succ;
  382.  
  383.     Forbid();
  384.     msg = (struct IntuiMessage *)win->UserPort->mp_MsgList.lh_Head;
  385.     while(succ = msg->ExecMessage.mn_Node.ln_Succ)
  386.     {
  387.     if(msg->IDCMPWindow == win)
  388.     {
  389.         Remove((struct Node *)msg);
  390.         Permit();
  391.         return(msg);
  392.     }
  393.     msg = (struct IntuiMessage *)succ;
  394.     }
  395.     Permit();
  396.     return(FALSE);
  397. }
  398.  
  399. void
  400. sys_activate_win(VW *vw)
  401. {
  402.     WindowToFront(vw->vw_Window);
  403.     ActivateWindow(vw->vw_Window);
  404. }
  405.  
  406. void
  407. sys_set_vw_pos(VW *vw, long x, long y, long w, long h)
  408. {
  409.     if(vw->vw_Flags & VWFF_SLEEPING)
  410.     {
  411.     vw->vw_WindowSys.ws_OldDimensions[0] = x;
  412.     vw->vw_WindowSys.ws_OldDimensions[1] = y;
  413.     vw->vw_WindowSys.ws_OldDimensions[2] = w;
  414.     vw->vw_WindowSys.ws_OldDimensions[3] = h;
  415.     }
  416.     else
  417.     {
  418.     ChangeWindowBox(vw->vw_Window, x, y, w, h);
  419.     vw->vw_DeferRefresh = 1;
  420.     }
  421. }
  422.  
  423. static struct EasyStruct ezstruct =
  424. {
  425.     sizeof(struct EasyStruct),
  426.     0,
  427.     "Jade request...",
  428.     NULL,
  429.     NULL,
  430. };
  431.  
  432. int
  433. ami_ezreq(u_char *bodyFmt, u_char *gadFmt, long arg1, ...)
  434. {
  435.     ezstruct.es_TextFormat = bodyFmt;
  436.     ezstruct.es_GadgetFormat = gadFmt;
  437.     return(EasyRequestArgs(curr_vw->vw_Window, &ezstruct, NULL, &arg1));
  438. }
  439.  
  440. _PR VALUE cmd_req(VALUE body, VALUE gads);
  441. DEFUN("req", cmd_req, subr_req, (VALUE body, VALUE gads), V_Subr2, DOC_req) /*
  442. ::doc:req::
  443. req BODY-STRING GADGETS-STRING
  444. <AMIGA-ONLY>
  445.  
  446. Function to do a request.
  447. Result is number of gadget pressed (starting at 1 for leftmost gadget and
  448. incrementing by one, rightmost gadget is 0.
  449. ::end:: */
  450. {
  451.     DECLARE1(body, STRINGP);
  452.     DECLARE2(gads, STRINGP);
  453.     return(make_number(ami_ezreq(VSTR(body), VSTR(gads), 0)));
  454. }
  455.  
  456. int
  457. sys_set_font(VW *vw)
  458. {
  459.     struct TextAttr ta;
  460.     struct TextFont *tf;
  461.  
  462.     ta.ta_Name = VSTR(vw->vw_FontName);
  463.     ta.ta_YSize = vw->vw_WindowSys.ws_FontSize;
  464.     ta.ta_Style = FS_NORMAL;
  465.     ta.ta_Flags = 0;
  466.  
  467.     if(tf = OpenDiskFont(&ta))
  468.     {
  469.     if(tf->tf_Flags & FPF_PROPORTIONAL)
  470.     {
  471.         CloseFont(tf);
  472.         return(FALSE);
  473.     }
  474.     if(vw->vw_Font)
  475.         CloseFont(vw->vw_Font);
  476.     vw->vw_Font = tf;
  477.     vw->vw_FontX = vw->vw_Font->tf_XSize;
  478.     vw->vw_FontY = vw->vw_Font->tf_YSize;
  479.     if(vw->vw_Window)
  480.     {
  481.         SetFont(vw->vw_WindowSys.ws_Rp, tf);
  482.         sys_update_dimensions(vw);
  483.     }
  484.     return(TRUE);
  485.     }
  486.     return(FALSE);
  487. }
  488.  
  489. void
  490. sys_unset_font(VW *vw)
  491. {
  492.     if(vw->vw_Font)
  493.     {
  494.     CloseFont(vw->vw_Font);
  495.     vw->vw_Font = NULL;
  496.     }
  497. }
  498.  
  499. _PR VALUE cmd_set_font(VALUE font, VALUE vw);
  500. DEFUN_INT("set-font", cmd_set_font, subr_set_font, (VALUE font, VALUE vw), V_Subr2, DOC_set_font, "sFont name (`FONT_NAME-SIZE'): ")
  501. {
  502.     VALUE oldfont, newfont;
  503.     LONG oldsize, newsize;
  504.     u_char *tmp;
  505.     DECLARE1(font, STRINGP);
  506.     if(!WINDOWP(vw))
  507.     vw = VAL(curr_vw);
  508.     oldfont = VWIN(vw)->vw_FontName;
  509.     oldsize = VWIN(vw)->vw_WindowSys.ws_FontSize;
  510.     tmp = strrchr(VSTR(font), '-');
  511.     if(!tmp)
  512.     return(cmd_signal(sym_error, list_2(MKSTR("No font-size specified"),
  513.                         font)));
  514.     newsize = atol(tmp+1);
  515.     newfont = string_dupn(VSTR(font), tmp - VSTR(font));
  516.     VWIN(vw)->vw_WindowSys.ws_FontSize = newsize;
  517.     VWIN(vw)->vw_FontName = newfont;
  518.     if(sys_set_font(VWIN(vw)))
  519.     {
  520.     VWIN(vw)->vw_Flags |= VWFF_FORCE_REFRESH;
  521.     return(sym_t);
  522.     }
  523.     else
  524.     {
  525.     cmd_signal(sym_error, list_2(MKSTR("Can't open font"), font));
  526.     VWIN(vw)->vw_FontName = oldfont;
  527.     VWIN(vw)->vw_WindowSys.ws_FontSize = oldsize;
  528.     return(NULL);
  529.     }
  530. }
  531.  
  532. _PR VALUE var_pub_screen(VALUE val);
  533. DEFUN("pub-screen", var_pub_screen, subr_pub_screen, (VALUE val), V_Var, DOC_pub_screen) /*
  534. ::doc:pub_screen::
  535. This variable controls the name of the public-screen which the window
  536. opens onto. It is only available when running on an Amiga.
  537. ::end:: */
  538. {
  539.     VW *vw = curr_vw;
  540.     if(val)
  541.     {
  542.     if(STRINGP(val))
  543.         vw->vw_WindowSys.ws_ScreenName = val;
  544.     return(val);
  545.     }
  546.     else
  547.     return(vw->vw_WindowSys.ws_ScreenName);
  548. }
  549.  
  550. /*
  551.  * Used when the name of a TX is changed. All sleeping views have their title
  552.  * display updated.
  553.  */
  554. void
  555. sys_reset_sleep_titles(TX *tx)
  556. {
  557.     VW *vw = view_chain;
  558.     while(vw)
  559.     {
  560.     if(vw->vw_Window && (vw->vw_Tx == tx)
  561.        && (vw->vw_Flags & VWFF_SLEEPING))
  562.     {
  563.         SetWindowTitles(vw->vw_Window, VSTR(tx->tx_BufferName),
  564.                 (UBYTE *)~0);
  565.     }
  566.     vw = vw->vw_Next;
  567.     }
  568. }
  569.  
  570. _PR VALUE cmd_screen_width(void);
  571. DEFUN("screen-width", cmd_screen_width, subr_screen_width, (void), V_Subr0, DOC_screen_width)
  572. {
  573.     return(make_number(curr_vw->vw_Window->WScreen->Width));
  574. }
  575.  
  576. _PR VALUE cmd_screen_height(void);
  577. DEFUN("screen-height", cmd_screen_height, subr_screen_height, (void), V_Subr0, DOC_screen_height)
  578. {
  579.     return(make_number(curr_vw->vw_Window->WScreen->Height));
  580. }
  581.  
  582. _PR VALUE cmd_window_left_edge(void);
  583. DEFUN("window-left-edge", cmd_window_left_edge, subr_window_left_edge, (void), V_Subr0, DOC_window_left_edge)
  584. {
  585.     return(make_number(curr_vw->vw_Window->LeftEdge));
  586. }
  587.  
  588. _PR VALUE cmd_window_top_edge(void);
  589. DEFUN("window-top-edge", cmd_window_top_edge, subr_window_top_edge, (void), V_Subr0, DOC_window_top_edge)
  590. {
  591.     return(make_number(curr_vw->vw_Window->TopEdge));
  592. }
  593.  
  594. _PR VALUE cmd_window_width(void);
  595. DEFUN("window-width", cmd_window_width, subr_window_width, (void), V_Subr0, DOC_window_width)
  596. {
  597.     return(make_number(curr_vw->vw_Window->Width));
  598. }
  599.  
  600. _PR VALUE cmd_window_height(void);
  601. DEFUN("window-height", cmd_window_height, subr_window_height, (void), V_Subr0, DOC_window_height)
  602. {
  603.     return(make_number(curr_vw->vw_Window->Height));
  604. }
  605.  
  606. _PR VALUE cmd_window_bar_height(void);
  607. DEFUN("window-bar-heigth", cmd_window_bar_height, subr_window_bar_height, (void), V_Subr0, DOC_window_bar_height)
  608. {
  609.     return(make_number((LONG)curr_vw->vw_Window->BorderTop));
  610. }
  611.  
  612. bool
  613. sys_get_mouse_pos(POS *res, VW *vw)
  614. {
  615.     struct Window *wd = vw->vw_Window;
  616.     WORD x = wd->MouseX;
  617.     WORD y = wd->MouseY;
  618.     if(((x < wd->Width) && (x > (wd->Width - wd->BorderRight)))
  619.     || ((y > 0) && (y < wd->BorderTop)))
  620.     {
  621.     *res = vw->vw_CursorPos;
  622.     return(TRUE);
  623.     }
  624.     if(x >= wd->Width)
  625.     res->pos_Col = vw->vw_StartCol + vw->vw_MaxX + 1;
  626.     else if(x <= 0)
  627.     res->pos_Col = vw->vw_StartCol - 1;
  628.     else if(x < (wd->Width - wd->BorderRight))
  629.     res->pos_Col = vw->vw_StartCol + ((x - (WORD)vw->vw_XStartPix) / (WORD)vw->vw_FontX);
  630.  
  631.     if(y >= wd->Height)
  632.     res->pos_Line = vw->vw_StartLine + vw->vw_MaxY;
  633.     else if(y <= 0)
  634.     res->pos_Line = vw->vw_StartLine - 1;
  635.     else if(y > wd->BorderTop)
  636.     res->pos_Line = vw->vw_StartLine + ((y - (WORD)vw->vw_YStartPix) / (WORD)vw->vw_FontY);
  637.  
  638.     if(res->pos_Col < 0)
  639.     res->pos_Col = 0;
  640.     if(res->pos_Line < 0)
  641.     res->pos_Line = 0;
  642.     if(res->pos_Line >= vw->vw_Tx->tx_NumLines)
  643.     res->pos_Line = vw->vw_Tx->tx_NumLines - 1;
  644.     res->pos_Col = char_col(vw->vw_Tx, res->pos_Col, res->pos_Line);
  645.     return(TRUE);
  646. }
  647.  
  648. void
  649. sys_windows_init(void)
  650. {
  651.     ADD_SUBR(subr_req);
  652.     ADD_SUBR(subr_set_font);
  653.     ADD_SUBR(subr_pub_screen);
  654.     ADD_SUBR(subr_screen_width);
  655.     ADD_SUBR(subr_screen_height);
  656.     ADD_SUBR(subr_window_left_edge);
  657.     ADD_SUBR(subr_window_top_edge);
  658.     ADD_SUBR(subr_window_width);
  659.     ADD_SUBR(subr_window_height);
  660.     ADD_SUBR(subr_window_bar_height);
  661. }
  662.